/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.testis.wirelesssecuritymodule.services;

import org.testis.data.TestStepException;
import org.testis.data.TestStepResultType;
import org.testis.logging.AtofLogLevel;
import org.testis.logging.LogSenderService;
import org.testis.nicmodule.core.NetworkInterfaceController;
import org.testis.nicmodule.core.NetworkInterfaceControllerFactory;
import org.testis.services.AtofModuleAction;
import org.testis.services.AtofModuleService;
import org.testis.utils.WmiNetworkAdapters;
import org.testis.wirelesssecuritymodule.core.WirelessConnectionChecker;
import org.testis.wirelesssecuritymodule.core.WirelessConnectionCheckerFactory;
import org.testis.wirelesssecuritymodule.core.WirelessConnectionTaskExecutor;
import org.testis.wirelesssecuritymodule.core.WirelessSecurityModuleException;
import org.testis.wirelesssecuritymodule.core.WirelessSecurityModuleExceptionType;
import org.testis.wirelesssecuritymodule.data.WirelessSecurityModuleDataObject;

/**
 *
 * @author root
 */
public class WirelessSecurityModuleConnectWirelessAndVerify extends AtofModuleAction {

    private WmiNetworkAdapters _wmiAdapters;

    @Override
    public boolean operateRequest(AtofModuleService request) {
        _wmiAdapters = new WmiNetworkAdapters();
        WirelessSecurityModuleDataObject dataObj =
                (WirelessSecurityModuleDataObject) request.getDataObj();
        try {
            dataObj.setConnectionState("NOT_CONNECTED");
            LogSenderService.putMessageOnQueue(
                    "WirelessSecurityModuleRunWpaSupplicantAction",
                    AtofLogLevel.INFO,
                    "Trying for connecting to wireless network...",
                    dataObj.getMessageId());

            dataObj.setStopExecution(true);
            LogSenderService.putMessageOnQueue(
                    "WirelessSecurityModuleRunWpaSupplicantAction",
                    AtofLogLevel.INFO,
                    "Trying to find iface...",
                    dataObj.getMessageId());


            String nicGuid = _wmiAdapters.getGuidByName(dataObj.getParamInterface());
            if (nicGuid == null || nicGuid.isEmpty()) {
                throw new WirelessSecurityModuleException(
                        WirelessSecurityModuleExceptionType.WIRELESS_ADAPTER_NOT_FOUND,
                        "WirelessConnectionSupplier:wireless adapter \"" + dataObj.getParamInterface() + "\" not found. "
                        + "Possible reasons: Network card may be disabled or not connected...");
            }

            LogSenderService.putMessageOnQueue(
                    "WirelessSecurityModuleRunWpaSupplicantAction",
                    AtofLogLevel.INFO,
                    "Iface found=" + nicGuid + "...",
                    dataObj.getMessageId());
            WirelessConnectionChecker cliWrapper = WirelessConnectionCheckerFactory.getInstance(nicGuid);

            try {
                cliWrapper.runCommand("disconnect");
            } catch (WirelessSecurityModuleException ex) {
                LogSenderService.putMessageOnQueue(
                        "WirelessSecurityModuleConnectWirelessAndVerify",
                        AtofLogLevel.ERROR,
                        ex.getMessage()
                        + "...Terminating wireless connection...Error:" + ex.getMessage(),
                        dataObj.getMessageId());
            } catch (Exception ex) {
                LogSenderService.putMessageOnQueue(
                        "WirelessSecurityModuleConnectWirelessAndVerify",
                        AtofLogLevel.ERROR,
                        ex.getMessage()
                        + "...Terminating wireless connection...Error:" + ex.getMessage(),
                        dataObj.getMessageId());
            }
            dataObj.setNicGuid(nicGuid);
            WirelessConnectionTaskExecutor.getInstance().executeTask(dataObj);
            dataObj.setStopExecution(false);
            WirelessConnectionTaskExecutor.getInstance().executeTask(dataObj);

            boolean result = false;

            int retryCount = 20;
            NetworkInterfaceController nicCtrl = NetworkInterfaceControllerFactory.createInstance("Wlan", nicGuid);
            while (retryCount > 0) {
                try {
                    Thread.sleep(3000);
                    String outputStatus = cliWrapper.runCommand("status");
                    String ipAddress = nicCtrl.getNetworkOs().getIp(dataObj.getParamInterface());
                    LogSenderService.putMessageOnQueue(
                            "WirelessSecurityModuleConnectWirelessAndVerify",
                            AtofLogLevel.INFO,
                            "Wireless Connection Status:" + outputStatus + " ipAddress:" + ipAddress,
                            dataObj.getMessageId());
                    if (cliWrapper.isConnected()) {
                        if (ipAddress != null) {
                            if (!ipAddress.equals("0.0.0.0")) {
                                if (!ipAddress.startsWith("169")) {
                                    result = true;
                                    dataObj.setConnectionState("CONNECTED");
                                    break;
                                }
                            }
                        }
                    }
                } catch (WirelessSecurityModuleException ex) {
                    LogSenderService.putMessageOnQueue(
                            "WirelessSecurityModuleConnectWirelessAndVerify",
                            AtofLogLevel.ERROR,
                            ex.getMessage()
                            + "...Checking wireless connection...Iface:" + nicGuid,
                            dataObj.getMessageId());
                } catch (Exception ex) {
                    LogSenderService.putMessageOnQueue(
                            "WirelessSecurityModuleConnectWirelessAndVerify",
                            AtofLogLevel.ERROR,
                            ex.getMessage()
                            + "...Checking wireless connection...Iface:" + nicGuid,
                            dataObj.getMessageId());
                } finally {
                    retryCount--;
                }
            }
            AtofLogLevel level = result ? AtofLogLevel.INFO : AtofLogLevel.ERROR;
            LogSenderService.putMessageOnQueue(
                    "WirelessSecurityModuleRunWpaSupplicantAction",
                    level,
                    "Connection to wireless network resulted:"
                    + Boolean.valueOf(result),
                    dataObj.getMessageId());
            return result;

        } catch (WirelessSecurityModuleException ex) {
            throw new TestStepException(TestStepResultType.FAILURE,
                    ex.getMessage() + " Error type:" + ex.getResultType().name());
        } catch (Exception ex) {
            throw new TestStepException(TestStepResultType.FAILURE,
                    ex.getMessage());
        }
    }
}
